package com.cw.java8.optional;

import com.cw.java8.functionInterface.Person;

import java.util.Objects;
import java.util.Optional;

/**
 * Optional 常用API
 */
public class OptionalTest {
    //例如，我们需要过滤出年龄在25岁到35岁之前的人群，那在Java8之前我们需要创建一个如下的方法来检测每个人的年龄范围是否在25岁到35岁之前。
    public boolean filterPerson(Person person) {
        boolean isInRange = false;
        if (person != null && person.getAge() >= 25 && person.getAge() <= 35) {
            isInRange = true;
        }
        return isInRange;
    }

    public boolean filterPersonByOptional(Person person){
        return Optional.ofNullable(person).map(Person::getAge).filter(p -> p >= 25).filter(p -> p <= 35).isPresent();
    }

        public static void main(String[] args) {
        String str = "Java";

        //1.构建Optional对象，将一个值放入Optional容器，str可以是空null
        Optional<String> optional = Optional.ofNullable(str);

        //2.判断容器是否存在值，存在返回true，不存在返回false
        boolean flag = optional.isPresent();
        System.out.println("容器是否存在值：" + flag);

        //3.判断容器是否存在值，存在值，采用一个消费者去消费
        optional.ifPresent((String s) -> {
            System.out.println("消费到的值是：" + s);
        });

        //4.Optional容器数据获取
        String value = optional.get();
        System.out.println("从容器中获取到的值是:" + value);

        //5.过滤容器中的值，满足过滤条件就返回本身的容器，否则返回一个新建的空的容器
        Optional<String> afterFilter = optional.filter((String s) -> {
            return s == null;
        });
        System.out.println("过滤后容器是否有值：" + afterFilter.isPresent());

        //6.给一个为空的容器添加一个默认值返回
        String defaultValue = afterFilter.orElse("Mysql");
        System.out.println("返回的默认值为：" + defaultValue);

        //7.使用链式调用+方法引用优雅的整合第5和第6步
        // 过滤容器中的值，如果过滤后容器中的值为空值，那么返回一个默认值
        String buildValue = optional.filter(Objects::isNull).orElse("Mysql");
        System.out.println("链式调用返回的值是：" + buildValue);
        String buildValue2 = optional.filter(Objects::nonNull).orElse("Mysql2");
        System.out.println("链式调用返回的值是：" + buildValue2);

        //8.如果值存在，为容器中的值进行添加方法进行加工和处理，然后返回一个包含加工后的容器
        Optional processOptional = optional.map((String s) -> {
            return "认真学习" + s;
        });
        System.out.println("加工后从容器得到的值是：" + processOptional.get());

        //9.过滤容器中的值，过滤后如果为空值，那么抛出一个异常
        Optional<String> nullOptional = Optional.ofNullable(null);
        nullOptional.filter(Objects::nonNull).orElseThrow(() -> {
            return new RuntimeException("容器中没有值");
        });

        //注意：方法getName返回的是一个Optional对象，如果使用map，我们还需要再调用一次get()方法，而使用flatMap()就不需要了。
        String len = null;
        Integer integer = Optional.ofNullable(len).map(s -> s.length()).orElse(0);
        System.out.println("integer = " + integer);
        Person person = new Person("evan", 18);
        Optional.ofNullable(person).map(p -> p.getName()).orElse("");
        Optional.ofNullable(person).flatMap(p -> Optional.ofNullable(p.getName())).orElse("");

        }
}
